home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / role / Ang261Lib.lha / src / io.c < prev    next >
C/C++ Source or Header  |  1994-10-22  |  32KB  |  1,563 lines

  1. /*
  2.  * io.c: terminal I/O code, uses the curses package 
  3.  *
  4.  * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke 
  5.  *
  6.  * This software may be copied and distributed for educational, research, and
  7.  * not for profit purposes provided that this copyright and statement are
  8.  * included in all such copies. 
  9.  */
  10.  
  11. #ifdef linux
  12. #include <bsd/sgtty.h>
  13. #endif
  14.  
  15. #ifdef MSDOS
  16. #include <stdio.h>
  17. #include <process.h>
  18. #endif
  19.  
  20. #if defined(NLS) && defined(lint)
  21. /* for AIX, don't let curses include the NL stuff */
  22. #undef NLS
  23. #endif
  24.  
  25. #if !defined(GEMDOS)
  26.  
  27. #ifdef MAC
  28. #include <scrnmgr.h>
  29. #else
  30. #ifdef linux
  31. #include <ncurses.h>
  32. #else
  33. #include <curses.h>
  34. #endif
  35. #endif
  36.  
  37. #else
  38. #define ATARIST_MWC
  39. #include "curses.h"
  40. #include <osbind.h>
  41. long                wgetch();
  42. char               *getenv();
  43. #endif
  44.  
  45. #include "constant.h"
  46. #include "config.h"
  47. #include "types.h"
  48. #include "externs.h"
  49.  
  50. #include <ctype.h>
  51.  
  52. #if defined(SYS_V) && defined(lint)
  53. /*
  54.  * for AIX, prevent hundreds of unnecessary lint errors, must define before
  55.  * signal.h is included 
  56.  */
  57. #define _h_IEEETRAP
  58. typedef struct {
  59.     int stuff;
  60. } fpvmach;
  61.  
  62. #endif
  63.  
  64. #if defined(MSDOS)
  65. #if defined(ANSI)
  66. #include "ms_ansi.h"
  67. #endif
  68. #else                   /* not msdos */
  69. #if !defined(ATARIST_MWC) && !defined(MAC)
  70. #ifndef VMS
  71. #include <sys/ioctl.h>
  72. #endif
  73. #include <signal.h>
  74. #endif
  75. #endif
  76.  
  77. #ifndef USG
  78. /* only needed for Berkeley UNIX */
  79. #include <sys/param.h>
  80. #include <sys/file.h>
  81. #include <sys/types.h>
  82. #endif
  83.  
  84. #ifdef USG
  85. #ifndef ATARIST_MWC
  86. #include <string.h>
  87. #else
  88. #include "string.h"
  89. #endif /* !ATARIST_MWC */
  90. #if !defined(MAC) && !defined(MSDOS) && !defined(ATARIST_MWC) && !defined(__MINT__)
  91. #include <termio.h>
  92. #endif
  93. #else
  94. #ifndef VMS
  95. #include <strings.h>
  96. #include <sys/wait.h>
  97. #endif /* !VMS */
  98. #endif /* USG */
  99.  
  100. /* ARGH!  This is driving me up the wall!  Brute force never hurt... [cjh] */
  101. #if defined(__MINT__) && !defined(_WAIT_H)
  102. #include <wait.h>
  103. #endif
  104.  
  105. #if defined(SYS_V) && defined(lint)
  106. struct screen {
  107.     int                 dumb;
  108. };
  109.  
  110. #endif
  111.  
  112. /*
  113.  * Fooling lint. Unfortunately, c defines all the TIO.      -CJS- constants to
  114.  * be long, and lint expects them to be int. Also, ioctl is sometimes called
  115.  * with just two arguments. The following definition keeps lint happy. It may
  116.  * need to be reset for different systems.     
  117.  */
  118. #ifndef MAC
  119. #ifdef lint
  120. #ifdef Pyramid
  121. /* Pyramid makes constants greater than 65535 into long! Gakk! -CJS- */
  122. /* ARGSUSED */
  123. /* VARARGS2 */
  124. static 
  125.     Ioctl(i, l, p) long l;
  126.     char               *p;
  127. {
  128.     return 0;
  129. }
  130.  
  131. #else
  132. /* ARGSUSED */
  133. /* VARARGS2 */
  134. static 
  135.     Ioctl(i, l, p) char *p;
  136. {
  137.     return 0;
  138. }
  139.  
  140. #endif
  141. #define ioctl        Ioctl
  142. #endif
  143.  
  144. #if !defined(USG) && defined(lint)
  145. /*
  146.  * This use_value hack is for curses macros which return a value, but don't
  147.  * shut up about it when you try to tell them (void).     
  148.  */
  149. /* only needed for Berkeley UNIX */
  150. int                 Use_value;
  151.  
  152. #define use_value   Use_value +=
  153. #else
  154. #define use_value
  155. #endif
  156.  
  157. #if defined(SYS_V) && defined(lint)
  158. /*
  159.  * This use_value2 hack is for curses macros which use a conditional
  160.  * expression, and which say null effect even if you cast to (void). 
  161.  */
  162. /* only needed for SYS V */
  163. int                 Use_value2;
  164.  
  165. #define use_value2  Use_value2 +=
  166. #else
  167. #define use_value2
  168. #endif
  169.  
  170. #endif
  171.  
  172. #ifndef MAC
  173. char *getenv();
  174.  
  175. #endif
  176.  
  177. #if !defined(MAC) && !defined(MSDOS) && !defined(ATARIST_MWC) && !defined(__MINT__)
  178. #ifdef USG
  179. static struct termio save_termio;
  180.  
  181. #else
  182. #ifndef VMS
  183. static struct ltchars save_special_chars;
  184. static struct sgttyb save_ttyb;
  185. static struct tchars save_tchars;
  186. static int          save_local_chars;
  187.  
  188. #endif
  189. #endif
  190. #endif
  191.  
  192. #ifndef MAC
  193. static int     curses_on = FALSE;
  194. static WINDOW *savescr;       /* Spare window for saving the screen.
  195.                     * -CJS- */
  196.  
  197. #endif
  198.  
  199. #ifdef MAC
  200. /* Attributes of normal and hilighted characters */
  201. #define ATTR_NORMAL    attrNormal
  202. #define ATTR_HILITED    attrReversed
  203. #endif
  204.  
  205. #ifndef MAC
  206. #ifdef SIGTSTP
  207. /*
  208.  * suspend()                               -CJS-
  209.  * Handle the stop and start signals. This ensures that the log is up to
  210.  * date, and that the terminal is fully reset and restored.  
  211.  */
  212. int 
  213. suspend()
  214. {
  215. #ifdef USG
  216. /*
  217.  * for USG systems with BSDisms that have SIGTSTP defined, but don't actually
  218.  * implement it 
  219.  */
  220. #else
  221.     struct sgttyb  tbuf;
  222.     struct ltchars lcbuf;
  223.     struct tchars  cbuf;
  224.     int            lbuf;
  225.     long           time();
  226.  
  227.     py.misc.male |= 2;
  228.     (void)ioctl(0, TIOCGETP, (char *)&tbuf);
  229.     (void)ioctl(0, TIOCGETC, (char *)&cbuf);
  230.     (void)ioctl(0, TIOCGLTC, (char *)&lcbuf);
  231.     (void)ioctl(0, TIOCLGET, (char *)&lbuf);
  232.     restore_term();
  233.     (void)kill(0, SIGSTOP);
  234.     curses_on = TRUE;
  235.     (void)ioctl(0, TIOCSETP, (char *)&tbuf);
  236.     (void)ioctl(0, TIOCSETC, (char *)&cbuf);
  237.     (void)ioctl(0, TIOCSLTC, (char *)&lcbuf);
  238.     (void)ioctl(0, TIOCLSET, (char *)&lbuf);
  239.     (void)touchwin(curscr);
  240.     (void)wrefresh(curscr);
  241.     cbreak();
  242.     noecho();
  243.     py.misc.male &= ~2;
  244. #endif
  245.     return 0;
  246. }
  247.  
  248. #endif
  249. #endif
  250.  
  251. /* initializes curses routines */
  252. void 
  253. init_curses()
  254. #ifdef MAC
  255. {
  256. /* Primary initialization is done in mac.c since game is restartable */
  257. /* Only need to clear the screen here */
  258.     Rect scrn;
  259.  
  260.     scrn.left = scrn.top = 0;
  261.     scrn.right = SCRN_COLS;
  262.     scrn.bottom = SCRN_ROWS;
  263.     EraseScreen(&scrn);
  264.     UpdateScreen();
  265. }
  266.  
  267. #else
  268. {
  269.     int i, y, x;
  270.  
  271. #ifndef USG
  272.     (void)ioctl(0, TIOCGLTC, (char *)&save_special_chars);
  273.     (void)ioctl(0, TIOCGETP, (char *)&save_ttyb);
  274.     (void)ioctl(0, TIOCGETC, (char *)&save_tchars);
  275.     (void)ioctl(0, TIOCLGET, (char *)&save_local_chars);
  276. #else
  277. #if !defined(VMS) && !defined(MSDOS) && !defined(ATARIST_MWC) && !defined(__MINT__)
  278.     (void)ioctl(0, TCGETA, (char *)&save_termio);
  279. #endif
  280. #endif
  281.  
  282. #ifdef ATARIST_MWC
  283.     WINDOW *newwin();
  284.  
  285.     initscr();
  286.     if (ERR)
  287. #else
  288. #if defined(USG) && !defined(PC_CURSES)    /* PC curses returns ERR */
  289.     if (initscr() == NULL)
  290. #else
  291.     if (initscr() == ERR)
  292. #endif
  293. #endif
  294.     {
  295.     (void)printf("Error allocating screen in curses package.\n");
  296.     exit(1);
  297.     }
  298.     if (LINES < 24 || COLS < 80) { /* Check we have enough screen. -CJS- */
  299.     (void)printf(
  300.       "Your screen is too small for Angband; you need at least 80x24.\n");
  301.     exit(1);
  302.     }
  303. #ifdef SIGTSTP
  304. #ifdef __MINT__
  305.     (void)signal(SIGTSTP, (__Sigfunc)suspend);
  306. #else
  307.     (void)signal(SIGTSTP, suspend);
  308. #endif
  309. #endif
  310.  
  311.     if ((savescr = newwin(0, 0, 0, 0)) == NULL) {
  312.     (void)printf("Out of memory in starting up curses.\n");
  313.     exit_game();
  314.     }
  315.     (void)clear();
  316.     (void)refresh();
  317.     moriaterm();
  318.  
  319. /* check tab settings, exit with error if they are not 8 spaces apart */
  320. #ifndef AMIGA
  321. #ifdef ATARIST_MWC
  322.     move(0, 0);
  323. #else
  324.     (void)move(0, 0);
  325. #endif
  326.     for (i = 1; i < 10; i++) {
  327. #ifdef ATARIST_MWC
  328.     addch('\t');
  329. #else
  330.     (void)addch('\t');
  331. #endif
  332.     getyx(stdscr, y, x);
  333.     if (y != 0 || x != i * 8)
  334.         break;
  335.     }
  336.     if (i != 10) {
  337.     msg_print("Tabs must be set 8 spaces apart.");
  338.     exit_game();
  339.     }
  340. #endif
  341. }
  342.  
  343. #endif
  344.  
  345. /* Set up the terminal into a suitable state for moria.     -CJS- */
  346. void 
  347. moriaterm()
  348. #ifdef MAC
  349. /* Nothing to do on Mac */
  350. {
  351. }
  352.  
  353. #else
  354. {
  355. #if !defined(MSDOS) && !defined(ATARIST_MWC) && !defined(__MINT__)
  356. #ifdef USG
  357.     struct termio  tbuf;
  358.  
  359. #else
  360.     struct ltchars lbuf;
  361.     struct tchars  buf;
  362.  
  363. #endif
  364. #endif
  365.  
  366.     curses_on = TRUE;
  367. #ifndef BSD4_3
  368.     use_value crmode();
  369.  
  370. #else
  371.     use_value cbreak();
  372.  
  373. #endif
  374.     use_value noecho();
  375.  
  376. /* can not use nonl(), because some curses do not handle it correctly */
  377. #ifdef MSDOS
  378.     msdos_raw();
  379. #else
  380. #if !defined(ATARIST_MWC) && !defined(__MINT__)
  381. #ifdef USG
  382.     (void)ioctl(0, TCGETA, (char *)&tbuf);
  383. /* disable all of the normal special control characters */
  384.     tbuf.c_cc[VINTR] = (char)3;       /* control-C */
  385.     tbuf.c_cc[VQUIT] = (char)-1;
  386.     tbuf.c_cc[VERASE] = (char)-1;
  387.     tbuf.c_cc[VKILL] = (char)-1;
  388.     tbuf.c_cc[VEOF] = (char)-1;
  389.  
  390. /* don't know what these are for */
  391.     tbuf.c_cc[VEOL] = (char)-1;
  392.     tbuf.c_cc[VEOL2] = (char)-1;
  393.  
  394. /* stuff needed when !icanon, i.e. cbreak/raw mode */
  395.     tbuf.c_cc[VMIN] = 1;       /* Input should wait for at least 1 char */
  396.     tbuf.c_cc[VTIME] = 0;       /* no matter how long that takes. */
  397.  
  398.     (void)ioctl(0, TCSETA, (char *)&tbuf);
  399. #else
  400. #ifndef VMS
  401. /*
  402.  * disable all of the special characters except the suspend char, interrupt
  403.  * char, and the control flow start/stop characters 
  404.  */
  405.     (void)ioctl(0, TIOCGLTC, (char *)&lbuf);
  406.     lbuf.t_suspc = (char)26;       /* control-Z */
  407.     lbuf.t_dsuspc = (char)-1;
  408.     lbuf.t_rprntc = (char)-1;
  409.     lbuf.t_flushc = (char)-1;
  410.     lbuf.t_werasc = (char)-1;
  411.     lbuf.t_lnextc = (char)-1;
  412.     (void)ioctl(0, TIOCSLTC, (char *)&lbuf);
  413.  
  414.     (void)ioctl(0, TIOCGETC, (char *)&buf);
  415.     buf.t_intrc = (char)3;       /* control-C */
  416.     buf.t_quitc = (char)-1;
  417.     buf.t_startc = (char)17;       /* control-Q */
  418.     buf.t_stopc = (char)19;       /* control-S */
  419.     buf.t_eofc = (char)-1;
  420.     buf.t_brkc = (char)-1;
  421.     (void)ioctl(0, TIOCSETC, (char *)&buf);
  422. #endif
  423. #endif
  424. #endif
  425. #endif
  426. }
  427.  
  428. #endif
  429.  
  430.  
  431. /* Dump IO to buffer                    -RAK-     */
  432. void 
  433. put_buffer(out_str, row, col)
  434. const char *out_str;
  435. int         row, col;
  436.  
  437. #ifdef MAC
  438. {
  439. /* The screen manager handles writes past the edge ok */
  440.     DSetScreenCursor(col, row);
  441.     DWriteScreenStringAttr(out_str, ATTR_NORMAL);
  442. }
  443.  
  444. #else
  445. {
  446.     vtype tmp_str;
  447.  
  448. /*
  449.  * truncate the string, to make sure that it won't go past right edge of
  450.  * screen 
  451.  */
  452.     if (col > 79)
  453.     col = 79;
  454.     (void)strncpy(tmp_str, out_str, 79 - col);
  455.     tmp_str[79 - col] = '\0';
  456.  
  457. #ifndef ATARIST_MWC
  458.     if (mvaddstr(row, col, tmp_str) == ERR)
  459. #else
  460.     mvaddstr(row, col, out_str);
  461.     if (ERR)
  462. #endif
  463.     {
  464.     abort();
  465.     /* clear msg_flag to avoid problems with unflushed messages */
  466.     msg_flag = 0;
  467.     (void)sprintf(tmp_str, "error in put_buffer, row = %d col = %d\n",
  468.               row, col);
  469.     prt(tmp_str, 0, 0);
  470.     bell();
  471.     /* wait so user can see error */
  472.     (void)sleep(2);
  473.     }
  474. }
  475.  
  476. #endif
  477.  
  478.  
  479. /* Dump the IO buffer to terminal            -RAK-     */
  480. void 
  481. put_qio()
  482. {
  483.     screen_change = TRUE;       /* Let inven_command know something has
  484.                     * changed. */
  485.     (void)refresh();
  486. }
  487.  
  488. /* Put the terminal in the original mode.               -CJS- */
  489. void 
  490. restore_term()
  491. #ifdef MAC
  492. /* Nothing to do on Mac */
  493. {
  494. }
  495.  
  496. #else
  497. {
  498.     if (!curses_on)
  499.     return;
  500.     put_qio();               /* Dump any remaining buffer */
  501. #ifdef MSDOS
  502.     (void)sleep(2);           /* And let it be read. */
  503. #endif
  504. #ifdef VMS
  505.     pause_line(15);
  506. #endif
  507. /* this moves curses to bottom right corner */
  508.     mvcur(curscr->_cury, curscr->_curx, LINES - 1, 0);
  509. #ifdef VMS
  510.     pause_line(15);
  511. #endif
  512.     endwin();               /* exit curses */
  513.     (void)fflush(stdout);
  514. #ifdef MSDOS
  515.     msdos_noraw();
  516.     (void)clear();
  517. #endif
  518. /* restore the saved values of the special chars */
  519. #ifdef USG
  520. #if !defined(MSDOS) && !defined(ATARIST_MWC) && !defined(__MINT__)
  521.     (void)ioctl(0, TCSETA, (char *)&save_termio);
  522. #endif
  523. #else
  524. #ifndef VMS
  525.     (void)ioctl(0, TIOCSLTC, (char *)&save_special_chars);
  526.     (void)ioctl(0, TIOCSETP, (char *)&save_ttyb);
  527.     (void)ioctl(0, TIOCSETC, (char *)&save_tchars);
  528.     (void)ioctl(0, TIOCLSET, (char *)&save_local_chars);
  529. #endif
  530. #endif
  531.     curses_on = FALSE;
  532. }
  533.  
  534. #endif
  535.  
  536.  
  537. void 
  538. shell_out()
  539. #ifdef MAC
  540. {
  541.     alert_error("This command is not implemented on the Macintosh.");
  542. }
  543.  
  544. #else
  545. {
  546. #ifdef USG
  547. #if !defined(MSDOS) && !defined(ATARIST_MWC) && !defined(__MINT__)
  548.     struct termio       tbuf;
  549.  
  550. #endif
  551. #else
  552.     struct sgttyb       tbuf;
  553.     struct ltchars      lcbuf;
  554.     struct tchars       cbuf;
  555.     int                 lbuf;
  556.  
  557. #endif
  558. #ifdef MSDOS
  559.     char               *comspec, key;
  560.  
  561. #else
  562. #ifdef ATARIST_MWC
  563.     char                comstr[80];
  564.     char               *str;
  565.     extern char       **environ;
  566.  
  567. #else
  568.     int                 val;
  569.     char               *str;
  570.  
  571. #endif
  572. #endif
  573.  
  574.     save_screen();
  575. /* clear screen and print 'exit' message */
  576.     clear_screen();
  577. #ifndef ATARIST_MWC
  578.     put_buffer("[Entering shell, type 'exit' to resume your game.]\n", 0, 0);
  579. #else
  580.     put_buffer("[Escaping to shell]\n", 0, 0);
  581. #endif
  582.     put_qio();
  583.  
  584. #ifdef USG
  585. #if !defined(MSDOS) && !defined(ATARIST_MWC) && !defined(__MINT__)
  586.     (void)ioctl(0, TCGETA, (char *)&tbuf);
  587. #endif
  588. #else
  589. #ifndef VMS
  590.     (void)ioctl(0, TIOCGETP, (char *)&tbuf);
  591.     (void)ioctl(0, TIOCGETC, (char *)&cbuf);
  592.     (void)ioctl(0, TIOCGLTC, (char *)&lcbuf);
  593.     (void)ioctl(0, TIOCLGET, (char *)&lbuf);
  594. #endif
  595. #endif
  596. /* would call nl() here if could use nl()/nonl(), see moriaterm() */
  597. #ifndef BSD4_3
  598.     use_value           nocrmode();
  599.  
  600. #else
  601.     use_value           nocbreak();
  602.  
  603. #endif
  604. #ifdef MSDOS
  605.     use_value           msdos_noraw();
  606.  
  607. #endif
  608.     use_value           echo();
  609.  
  610.     ignore_signals();
  611. #ifdef MSDOS               /* { */
  612.     if ((comspec = getenv("COMSPEC")) == NULL
  613.     || spawnl(P_WAIT, comspec, comspec, (char *)NULL) < 0) {
  614.     clear_screen();           /* BOSS key if shell failed */
  615.     put_buffer("M:\\> ", 0, 0);
  616.     do {
  617.         key = inkey();
  618.     } while (key != '!');
  619.     }
  620. #else                   /* MSDOS }{ */
  621. #ifndef ATARIST_MWC
  622.     val = fork();
  623.     if (val == 0) {
  624. #endif
  625.     default_signals();
  626. #ifdef USG
  627. #if !defined(MSDOS) && !defined(ATARIST_MWC) && !defined(__MINT__)
  628.     (void)ioctl(0, TCSETA, (char *)&save_termio);
  629. #endif
  630. #else
  631. #ifndef VMS
  632.     (void)ioctl(0, TIOCSLTC, (char *)&save_special_chars);
  633.     (void)ioctl(0, TIOCSETP, (char *)&save_ttyb);
  634.     (void)ioctl(0, TIOCSETC, (char *)&save_tchars);
  635.     (void)ioctl(0, TIOCLSET, (char *)&save_local_chars);
  636. #endif
  637. #endif
  638. #ifndef MSDOS
  639.     /* close scoreboard descriptor */
  640.     /* it is not open on MSDOS machines */
  641. #if 0
  642.     /* this file is not open now, see init_file() in files.c */
  643.     (void)close(highscore_fd);
  644. #endif
  645. #endif
  646.     if ((str = getenv("SHELL")))
  647. #ifndef ATARIST_MWC
  648.         (void)execl(str, str, (char *)0);
  649. #else
  650.         system(str);
  651. #endif
  652.     else
  653. #ifndef ATARIST_MWC
  654.         (void)execl("/bin/sh", "sh", (char *)0);
  655. #endif
  656.     msg_print("Cannot execute shell.");
  657. #ifndef ATARIST_MWC
  658.     exit(1);
  659.     }
  660.     if (val == -1) {
  661.     msg_print("Fork failed. Try again.");
  662.     return;
  663.     }
  664. #ifdef USG
  665.     (void)wait((int *)0);
  666. #else
  667.     (void)wait((union wait *) 0);
  668. #endif
  669. #endif                   /* ATARIST_MWC */
  670. #endif                   /* MSDOS } */
  671.     restore_signals();
  672. /* restore the cave to the screen */
  673.     restore_screen();
  674. #ifndef BSD4_3
  675.     use_value           crmode();
  676.  
  677. #else
  678.     use_value           cbreak();
  679.  
  680. #endif
  681.     use_value           noecho();
  682.  
  683. /* would call nonl() here if could use nl()/nonl(), see moriaterm() */
  684. #ifdef MSDOS
  685.     msdos_raw();
  686. #endif
  687. /* disable all of the local special characters except the suspend char */
  688. /* have to disable ^Y for tunneling */
  689. #ifdef USG
  690. #if !defined(MSDOS) && !defined(ATARIST_MWC) && !defined(__MINT__)
  691.     (void)ioctl(0, TCSETA, (char *)&tbuf);
  692. #endif
  693. #else
  694. #ifndef VMS
  695.     (void)ioctl(0, TIOCSLTC, (char *)&lcbuf);
  696.     (void)ioctl(0, TIOCSETP, (char *)&tbuf);
  697.     (void)ioctl(0, TIOCSETC, (char *)&cbuf);
  698.     (void)ioctl(0, TIOCLSET, (char *)&lbuf);
  699. #endif
  700. #endif
  701.     (void)wrefresh(curscr);
  702. }
  703.  
  704. #endif
  705.  
  706.  
  707. /*
  708.  * Returns a single character input from the terminal.    This silently -CJS-
  709.  * consumes ^R to redraw the screen and reset the terminal, so that this
  710.  * operation can always be performed at any input prompt.  inkey() never
  711.  * returns ^R.     
  712.  */
  713. char 
  714. inkey()
  715. #ifdef MAC
  716. /* The Mac does not need ^R, so it just consumes it */
  717. /* This routine does nothing special with direction keys */
  718. /* Just returns their keypad ascii value (e.g. '0'-'9') */
  719. /* Compare with inkeydir() below */
  720. {
  721.     char ch;
  722.     int  dir;
  723.     int  shift_flag, ctrl_flag;
  724.  
  725.     put_qio();
  726.     command_count = 0;
  727.  
  728.     do {
  729.     macgetkey(&ch, FALSE);
  730.     } while (ch == CTRL('R'));
  731.  
  732.     dir = extractdir(ch, &shift_flag, &ctrl_flag);
  733.     if (dir != -1)
  734.     ch = '0' + dir;
  735.  
  736.     return (ch);
  737. }
  738.  
  739. #else
  740. {
  741.     int i;
  742.  
  743.     put_qio();               /* Dump IO buffer         */
  744.     command_count = 0;           /* Just to be safe -CJS- */
  745.     while (TRUE) {
  746. #ifdef MSDOS
  747.     i = msdos_getch();
  748. #else
  749.     i = getch();
  750. #endif
  751.  
  752.     /* some machines may not sign extend. */
  753.     if (i == EOF) {
  754.         eof_flag++;
  755.     /*
  756.      * avoid infinite loops while trying to call inkey() for a -more-
  757.      * prompt. 
  758.      */
  759.         msg_flag = FALSE;
  760.  
  761.         (void)refresh();
  762.         if (!character_generated || character_saved)
  763.         exit_game();
  764.         disturb(1, 0);
  765.         if (eof_flag > 100) {
  766.         /* just in case, to make sure that the process eventually dies */
  767.         panic_save = 1;
  768.         (void)strcpy(died_from, "(end of input: panic saved)");
  769.         if (!save_char()) {
  770.             (void)strcpy(died_from, "panic: unexpected eof");
  771.             death = TRUE;
  772.         }
  773.         exit_game();
  774.         }
  775.         return ESCAPE;
  776.     }
  777.     if (i != CTRL('R'))
  778.         return (char)i;
  779.     (void)wrefresh(curscr);
  780.     moriaterm();
  781.     }
  782. }
  783.  
  784. #endif
  785.  
  786.  
  787. #ifdef MAC
  788. char 
  789. inkeydir()
  790. /* The Mac does not need ^R, so it just consumes it */
  791. /* This routine translates the direction keys in rogue-like mode */
  792. /* Compare with inkeydir() below */
  793. {
  794.     char        ch;
  795.     int         dir;
  796.     int         shift_flag, ctrl_flag;
  797.     static char tab[9] = {
  798.     'b', 'j', 'n',
  799.     'h', '.', 'l',
  800.     'y', 'k', 'u'
  801.     };
  802.     static char shifttab[9] = {
  803.     'B', 'J', 'N',
  804.     'H', '.', 'L',
  805.     'Y', 'K', 'U'
  806.     };
  807.     static char ctrltab[9] = {
  808.     CTRL('B'), CTRL('J'), CTRL('N'),
  809.     CTRL('H'), '.', CTRL('L'),
  810.     CTRL('Y'), CTRL('K'), CTRL('U')
  811.     };
  812.  
  813.     put_qio();
  814.     command_count = 0;
  815.  
  816.     do {
  817.     macgetkey(&ch, FALSE);
  818.     } while (ch == CTRL('R'));
  819.  
  820.     dir = extractdir(ch, &shift_flag, &ctrl_flag);
  821.  
  822.     if (dir != -1) {
  823.     if (!rogue_like_commands) {
  824.         ch = '0' + dir;
  825.     } else {
  826.         if (ctrl_flag)
  827.         ch = ctrltab[dir - 1];
  828.         else if (shift_flag)
  829.         ch = shifttab[dir - 1];
  830.         else
  831.         ch = tab[dir - 1];
  832.     }
  833.     }
  834.     return (ch);
  835. }
  836.  
  837. #endif
  838.  
  839.  
  840. /* Flush the buffer                    -RAK-     */
  841. void 
  842. flush()
  843. #ifdef MAC
  844. {
  845. /* Removed put_qio() call.  Reduces flashing.  Doesn't seem to hurt. */
  846.     FlushScreenKeys();
  847. }
  848.  
  849. #else
  850. {
  851. #ifdef MSDOS
  852.     while (kbhit())
  853.     (void)getch();
  854. #else
  855. /*
  856.  * the code originally used ioctls, TIOCDRAIN, or TIOCGETP/TIOCSETP, or
  857.  * TCGETA/TCSETAF, however this occasionally resulted in loss of output, the
  858.  * happened especially often when rlogin from BSD to SYS_V machine, using
  859.  * check_input makes the desired effect a bit clearer 
  860.  */
  861. /* wierd things happen on EOF, don't try to flush input in that case */
  862.     if (!eof_flag)
  863.     while (check_input(0));
  864. #endif
  865.  
  866. /* used to call put_qio() here to drain output, but it is not necessary */
  867. }
  868.  
  869. #endif
  870.  
  871.  
  872. /* Clears given line of text                -RAK-     */
  873. void 
  874. erase_line(row, col)
  875. int row, col;
  876.  
  877. #ifdef MAC
  878. {
  879.     Rect line;
  880.  
  881.     if (row == MSG_LINE && msg_flag)
  882.     msg_print(NULL);
  883.  
  884.     line.left = col;
  885.     line.top = row;
  886.     line.right = SCRN_COLS;
  887.     line.bottom = row + 1;
  888.     DEraseScreen(&line);
  889. }
  890.  
  891. #else
  892. {
  893.     if (row == MSG_LINE && msg_flag)
  894.     msg_print(NULL);
  895.     (void)move(row, col);
  896.     clrtoeol();
  897. }
  898.  
  899. #endif
  900.  
  901.  
  902. /* Clears screen */
  903. void 
  904. clear_screen()
  905. #ifdef MAC
  906. {
  907.     Rect area;
  908.  
  909.     if (msg_flag)
  910.     msg_print(NULL);
  911.  
  912.     area.left = area.top = 0;
  913.     area.right = SCRN_COLS;
  914.     area.bottom = SCRN_ROWS;
  915.     DEraseScreen(&area);
  916. }
  917.  
  918. #else
  919. {
  920.     if (msg_flag)
  921.     msg_print(NULL);
  922.     touchwin(stdscr);
  923.     (void)clear();
  924.     refresh();
  925. }
  926.  
  927. #endif
  928.  
  929. void 
  930. clear_from(row)
  931. int row;
  932.  
  933. #ifdef MAC
  934. {
  935.     Rect area;
  936.  
  937.     area.left = 0;
  938.     area.top = row;
  939.     area.right = SCRN_COLS;
  940.     area.bottom = SCRN_ROWS;
  941.     DEraseScreen(&area);
  942. }
  943.  
  944. #else
  945. {
  946.     (void)move(row, 0);
  947.     clrtobot();
  948. }
  949.  
  950. #endif
  951.  
  952. /* Outputs a char to a given interpolated y, x position    -RAK-     */
  953. /* sign bit of a character used to indicate standout mode. -CJS */
  954. void 
  955. print(ch, row, col)
  956. int ch, row, col;
  957. {
  958.     row -= panel_row_prt;       /* Real co-ords convert to screen positions */
  959.     col -= panel_col_prt;
  960. #if 0
  961.     if (ch & 0x80)
  962.     standout();
  963. #endif
  964.     if (mvaddch(row, col, ch) == ERR) {
  965.     vtype               tmp_str;
  966.  
  967.     /* clear msg_flag to avoid problems with unflushed messages */
  968.     msg_flag = 0;
  969.     (void)sprintf(tmp_str, "error in print, row = %d col = %d\n", row, col);
  970.     prt(tmp_str, 0, 0);
  971.     bell();
  972.     /* wait so user can see error */
  973.     (void)sleep(2);
  974.     abort();
  975.     }
  976. #if 0
  977.     if (ch & 0x80)
  978.     standend();
  979. #endif
  980. }
  981.  
  982.  
  983. /* Moves the cursor to a given interpolated y, x position    -RAK-     */
  984. void 
  985. move_cursor_relative(row, col)
  986. int row, col;
  987.  
  988. #ifdef MAC
  989. {
  990.     row -= panel_row_prt;       /* Real co-ords convert to screen
  991.                     * positions */
  992.     col -= panel_col_prt;
  993.  
  994.     DSetScreenCursor(col, row);
  995. }
  996.  
  997. #else
  998. {
  999.     vtype tmp_str;
  1000.  
  1001.     row -= panel_row_prt;       /* Real co-ords convert to screen
  1002.                     * positions */
  1003.     col -= panel_col_prt;
  1004.     if (move(row, col) == ERR) {
  1005.     abort();
  1006.     /* clear msg_flag to avoid problems with unflushed messages */
  1007.     msg_flag = 0;
  1008.     (void)sprintf(tmp_str,
  1009.               "error in move_cursor_relative, row = %d col = %d\n",
  1010.               row, col);
  1011.     prt(tmp_str, 0, 0);
  1012.     bell();
  1013.     /* wait so user can see error */
  1014.     (void)sleep(2);
  1015.     }
  1016. }
  1017.  
  1018. #endif
  1019.  
  1020.  
  1021. /* Print a message so as not to interrupt a counted command. -CJS- */
  1022. void 
  1023. count_msg_print(p)
  1024. const char *p;
  1025. {
  1026.     int i;
  1027.  
  1028.     i = command_count;
  1029.     msg_print(p);
  1030.     command_count = i;
  1031. }
  1032.  
  1033.  
  1034. /* Outputs a line to a given y, x position        -RAK-     */
  1035. void 
  1036. prt(str_buff, row, col)
  1037. const char *str_buff;
  1038. int         row, col;
  1039.  
  1040. #ifdef MAC
  1041. {
  1042.     Rect line;
  1043.  
  1044.     if (row == MSG_LINE && msg_flag)
  1045.     msg_print(NULL);
  1046.  
  1047.     line.left = col;
  1048.     line.top = row;
  1049.     line.right = SCRN_COLS;
  1050.     line.bottom = row + 1;
  1051.     DEraseScreen(&line);
  1052.  
  1053.     put_buffer(str_buff, row, col);
  1054. }
  1055.  
  1056. #else
  1057. {
  1058.     if (row == MSG_LINE && msg_flag)
  1059.     msg_print(NULL);
  1060.     (void)move(row, col);
  1061.     clrtoeol();
  1062.     put_buffer(str_buff, row, col);
  1063. }
  1064.  
  1065. #endif
  1066.  
  1067.  
  1068. /* move cursor to a given y, x position */
  1069. void 
  1070. move_cursor(row, col)
  1071. int row, col;
  1072.  
  1073. #ifdef MAC
  1074. {
  1075.     DSetScreenCursor(col, row);
  1076. }
  1077.  
  1078. #else
  1079. {
  1080.     (void)move(row, col);
  1081. }
  1082.  
  1083. #endif
  1084.  
  1085.  
  1086. /* Outputs message to top line of screen                 */
  1087. /* These messages are kept for later reference.     */
  1088. void 
  1089. msg_print(str_buff)
  1090. const char *str_buff;
  1091. {
  1092.     char   in_char;
  1093.     static len = 0;
  1094.  
  1095.     if (msg_flag) {
  1096.     if (str_buff && (len + strlen(str_buff)) > 72) {
  1097.     /* ensure that the complete -more- message is visible. */
  1098.         if (len > 73)
  1099.         len = 73;
  1100.         put_buffer(" -more-", MSG_LINE, len);
  1101.     /* let sigint handler know that we are waiting for a space */
  1102.         wait_for_more = 1;
  1103.         do {
  1104.         in_char = inkey();
  1105.         } while ((in_char != ' ') && (in_char != ESCAPE) && (in_char != '\n') &&
  1106.              (in_char != '\r') && (!quick_messages));
  1107.         len = 0;
  1108.         wait_for_more = 0;
  1109.         (void)move(MSG_LINE, 0);
  1110.         clrtoeol();
  1111.  
  1112.     /* Make the null string a special case.  -CJS- */
  1113.         if (str_buff) {
  1114.         put_buffer(str_buff, MSG_LINE, 0);
  1115.         command_count = 0;
  1116.         last_msg++;
  1117.         if (last_msg >= MAX_SAVE_MSG)
  1118.             last_msg = 0;
  1119.         (void)strncpy(old_msg[last_msg], str_buff, VTYPESIZ);
  1120.         old_msg[last_msg][VTYPESIZ - 1] = '\0';
  1121.         len = strlen(str_buff) + 1;
  1122.         msg_flag = TRUE;
  1123.         } else {
  1124.         len = 0;
  1125.         msg_flag = FALSE;
  1126.         }
  1127.     } else {
  1128.         if (!str_buff) {
  1129.         if (len > 73)
  1130.             len = 73;
  1131.         put_buffer(" -more-", MSG_LINE, len);
  1132.         /* let sigint handler know that we are waiting for a space */
  1133.         wait_for_more = 1;
  1134.         do {
  1135.             in_char = inkey();
  1136.         } while ((in_char != ' ') && (in_char != ESCAPE)
  1137.              && (in_char != '\n') && (in_char != '\r') && (!quick_messages));
  1138.         wait_for_more = 0;
  1139.         len = 0;
  1140.         (void)move(MSG_LINE, 0);
  1141.         clrtoeol();
  1142.         msg_flag = FALSE;
  1143.         } else {
  1144.         put_buffer(str_buff, MSG_LINE, len);
  1145.         len += strlen(str_buff) + 1;
  1146.         command_count = 0;
  1147.         last_msg++;
  1148.         if (last_msg >= MAX_SAVE_MSG)
  1149.             last_msg = 0;
  1150.         (void)strncpy(old_msg[last_msg], str_buff, VTYPESIZ);
  1151.         old_msg[last_msg][VTYPESIZ - 1] = '\0';
  1152.         msg_flag = TRUE;
  1153.         }
  1154.     }
  1155.     } else {
  1156.     (void)move(MSG_LINE, 0);
  1157.     clrtoeol();
  1158.     if (str_buff) {
  1159.         put_buffer(str_buff, MSG_LINE, 0);
  1160.         command_count = 0;
  1161.         len = strlen(str_buff) + 1;
  1162.         last_msg++;
  1163.         if (last_msg >= MAX_SAVE_MSG)
  1164.         last_msg = 0;
  1165.         (void)strncpy(old_msg[last_msg], str_buff, VTYPESIZ);
  1166.         old_msg[last_msg][VTYPESIZ - 1] = '\0';
  1167.         msg_flag = TRUE;
  1168.     } else {
  1169.         msg_flag = FALSE;
  1170.         len = 0;
  1171.     }
  1172.     }
  1173. }
  1174.  
  1175. /* Used to verify a choice - user gets the chance to abort choice.  -CJS- */
  1176. int 
  1177. get_check(prompt)
  1178. const char *prompt;
  1179. {
  1180.     int res, y, x;
  1181.  
  1182.     prt(prompt, 0, 0);
  1183. #ifdef MAC
  1184.     GetScreenCursor(&x, &y);
  1185. #else
  1186.     getyx(stdscr, y, x);
  1187. #if defined(lint)
  1188. /* prevent message 'warning: y is unused' */
  1189.     x = y;
  1190. #endif
  1191.     res = y;
  1192. #endif
  1193.  
  1194.     if (x > 73)
  1195. #ifdef ATARIST_MWC
  1196.     move(0, 73);
  1197. #else
  1198.     (void)move(0, 73);
  1199. #endif
  1200. #ifdef MAC
  1201.     DWriteScreenStringAttr(" [y/n]", ATTR_NORMAL);
  1202. #else
  1203.     (void)addstr(" [y/n]");
  1204. #endif
  1205.     do {
  1206.     res = inkey();
  1207.     }
  1208.     while (res == ' ');
  1209.     erase_line(0, 0);
  1210.     if (res == 'Y' || res == 'y')
  1211.     return TRUE;
  1212.     else
  1213.     return FALSE;
  1214. }
  1215.  
  1216. /* Prompts (optional) and returns ord value of input char     */
  1217. /* Function returns false if <ESCAPE> is input     */
  1218. int 
  1219. get_com(prompt, command)
  1220. const char *prompt;
  1221. char       *command;
  1222. {
  1223.     int res;
  1224.  
  1225.     if (prompt)
  1226.     prt(prompt, 0, 0);
  1227.     *command = inkey();
  1228.     if (*command == 0 || *command == ESCAPE)
  1229.     res = FALSE;
  1230.     else
  1231.     res = TRUE;
  1232.     erase_line(MSG_LINE, 0);
  1233.     return (res);
  1234. }
  1235.  
  1236. #ifdef MAC
  1237. /* Same as get_com(), but translates direction keys from keypad */
  1238. int 
  1239. get_comdir(prompt, command)
  1240. char *prompt;
  1241. char *command;
  1242. {
  1243.     int res;
  1244.  
  1245.     if (prompt)
  1246.     prt(prompt, 0, 0);
  1247.     *command = inkeydir();
  1248.     if (*command == 0 || *command == ESCAPE)
  1249.     res = FALSE;
  1250.     else
  1251.     res = TRUE;
  1252.     erase_line(MSG_LINE, 0);
  1253.     return (res);
  1254. }
  1255.  
  1256. #endif
  1257.  
  1258.  
  1259. /* Gets a string terminated by <RETURN>         */
  1260. /* Function returns false if <ESCAPE> is input     */
  1261. int 
  1262. get_string(in_str, row, column, slen)
  1263. char *in_str;
  1264. int   row, column, slen;
  1265. {
  1266.     register int start_col, end_col, i;
  1267.     char        *p;
  1268.     int          flag, aborted;
  1269.  
  1270.     aborted = FALSE;
  1271.     flag = FALSE;
  1272.     (void)move(row, column);
  1273.     for (i = slen; i > 0; i--)
  1274.     (void)addch(' ');
  1275.     (void)move(row, column);
  1276.     start_col = column;
  1277.     end_col = column + slen - 1;
  1278.     if (end_col > 79) {
  1279.     slen = 80 - column;
  1280.     end_col = 79;
  1281.     }
  1282.     p = in_str;
  1283.     do {
  1284.     i = inkey();
  1285.     switch (i) {
  1286.       case ESCAPE:
  1287.         aborted = TRUE;
  1288.         break;
  1289.       case CTRL('J'):
  1290.       case CTRL('M'):
  1291.         flag = TRUE;
  1292.         break;
  1293.       case DELETE:
  1294.       case CTRL('H'):
  1295.         if (column > start_col) {
  1296.         column--;
  1297.         put_buffer(" ", row, column);
  1298.         move_cursor(row, column);
  1299.         *--p = '\0';
  1300.         }
  1301.         break;
  1302.       default:
  1303.         if (!isprint(i) || column > end_col)
  1304.         bell();
  1305.         else {
  1306. #ifdef MAC
  1307.         DSetScreenCursor(column, row);
  1308.         DWriteScreenCharAttr((char)i, ATTR_NORMAL);
  1309. #else
  1310.         use_value2          mvaddch(row, column, (char)i);
  1311.  
  1312. #endif
  1313.         *p++ = i;
  1314.         column++;
  1315.         }
  1316.         break;
  1317.     }
  1318.     }
  1319.     while ((!flag) && (!aborted));
  1320.     if (aborted)
  1321.     return (FALSE);
  1322. /* Remove trailing blanks     */
  1323.     while (p > in_str && p[-1] == ' ')
  1324.     p--;
  1325.     *p = '\0';
  1326.     return (TRUE);
  1327. }
  1328.  
  1329.  
  1330. /* Pauses for user response before returning        -RAK-     */
  1331. void 
  1332. pause_line(prt_line)
  1333. int prt_line;
  1334. {
  1335.     prt("[Press any key to continue.]", prt_line, 23);
  1336.     (void)inkey();
  1337.     erase_line(prt_line, 0);
  1338. }
  1339.  
  1340.  
  1341. /* Pauses for user response before returning        -RAK-     */
  1342. /* NOTE: Delay is for players trying to roll up "perfect"     */
  1343. /* characters.  Make them wait a bit.             */
  1344. void 
  1345. pause_exit(prt_line, delay)
  1346. int prt_line, delay;
  1347. {
  1348.     char dummy;
  1349.  
  1350.     prt("[Press any key to continue, or Q to exit.]", prt_line, 10);
  1351.     dummy = inkey();
  1352.     if (dummy == 'Q') {
  1353.     erase_line(prt_line, 0);
  1354. #ifndef MSDOS               /* PCs are slow enough as is  -dgk */
  1355.     if (delay > 0)
  1356.         (void)sleep((unsigned)delay);
  1357. #else
  1358.     /* prevent message about delay unused */
  1359.     dummy = delay;
  1360. #endif
  1361. #ifdef MAC
  1362.     enablefilemenu(FALSE);
  1363.     exit_game();
  1364.     enablefilemenu(TRUE);
  1365. #else
  1366.     exit_game();
  1367. #endif
  1368.     }
  1369.     erase_line(prt_line, 0);
  1370. }
  1371.  
  1372. #ifdef MAC
  1373. void 
  1374. save_screen()
  1375. {
  1376.     mac_save_screen();
  1377. }
  1378.  
  1379. void 
  1380. restore_screen()
  1381. {
  1382.     mac_restore_screen();
  1383. }
  1384.  
  1385. #else
  1386. void 
  1387. save_screen()
  1388. {
  1389.     overwrite(stdscr, savescr);
  1390. }
  1391.  
  1392. void 
  1393. restore_screen()
  1394. {
  1395.     overwrite(savescr, stdscr);
  1396.     touchwin(stdscr);
  1397. }
  1398.  
  1399. #endif
  1400.  
  1401. void 
  1402. bell()
  1403. {
  1404.     put_qio();
  1405. #ifdef MAC
  1406.     mac_beep();
  1407. #else
  1408.     (void)write(1, "\007", 1);
  1409. #endif
  1410. }
  1411.  
  1412. /* definitions used by screen_map() */
  1413. /* index into border character array */
  1414. #define TL 0               /* top left */
  1415. #define TR 1
  1416. #define BL 2
  1417. #define BR 3
  1418. #define HE 4               /* horizontal edge */
  1419. #define VE 5
  1420.  
  1421. /* character set to use */
  1422. #ifdef MSDOS
  1423. # ifdef ANSI
  1424. #   define CH(x)    (ansi ? screen_border[0][x] : screen_border[1][x])
  1425. # else
  1426. #   define CH(x)    (screen_border[1][x])
  1427. # endif
  1428. #else
  1429. #   define CH(x)    (screen_border[0][x])
  1430. #endif
  1431.  
  1432. /* Display highest priority object in the RATIO by RATIO area */
  1433. #define    RATIO 3
  1434.  
  1435. void 
  1436. screen_map()
  1437. {
  1438.     register int i, j;
  1439.     static int8u screen_border[2][6] = {
  1440.     {'+', '+', '+', '+', '-', '|'},    /* normal chars */
  1441.     {201, 187, 200, 188, 205, 186}    /* graphics chars */
  1442.     };
  1443.     int8u map[MAX_WIDTH / RATIO + 1];
  1444.     int8u tmp;
  1445.     int   priority[256];
  1446.     int   row, orow, col, myrow = 0, mycol = 0;
  1447.  
  1448. #ifndef MAC
  1449.     char  prntscrnbuf[80];
  1450.  
  1451. #endif
  1452.  
  1453.     for (i = 0; i < 256; i++)
  1454.     priority[i] = 0;
  1455.     priority['<'] = 5;
  1456.     priority['>'] = 5;
  1457.     priority['@'] = 10;
  1458. #ifdef MSDOS
  1459.     priority[wallsym] = (-5);
  1460.     priority[floorsym] = (-10);
  1461.     priority['±'] = (-1);
  1462. #else
  1463.     priority['#'] = (-5);
  1464.     priority['.'] = (-10);
  1465.     priority['x'] = (-1);
  1466. #endif
  1467.     priority['\''] = (-3);
  1468.     priority[' '] = (-15);
  1469.  
  1470.     save_screen();
  1471.     clear_screen();
  1472. #ifdef MAC
  1473.     DSetScreenCursor(0, 0);
  1474.     DWriteScreenCharAttr(CH(TL), ATTR_NORMAL);
  1475.     for (i = 0; i < MAX_WIDTH / RATIO; i++)
  1476.     DWriteScreenCharAttr(CH(HE), ATTR_NORMAL);
  1477.     DWriteScreenCharAttr(CH(TR), ATTR_NORMAL);
  1478. #else
  1479.     use_value2          mvaddch(0, 0, CH(TL));
  1480.  
  1481.     for (i = 0; i < MAX_WIDTH / RATIO; i++)
  1482.     (void)addch(CH(HE));
  1483.     (void)addch(CH(TR));
  1484. #endif
  1485.     orow = (-1);
  1486.     map[MAX_WIDTH / RATIO] = '\0';
  1487.     for (i = 0; i < MAX_HEIGHT; i++) {
  1488.     row = i / RATIO;
  1489.     if (row != orow) {
  1490.         if (orow >= 0) {
  1491. #ifdef MAC
  1492.         DSetScreenCursor(0, orow + 1);
  1493.         DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
  1494.         DWriteScreenString(map);
  1495.         DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
  1496. #else
  1497.         /* can not use mvprintw() on ibmpc, because PC-Curses is horribly
  1498.          * written, and mvprintw() causes the fp emulation library to be
  1499.          * linked with PC-Moria, makes the program 10K bigger 
  1500.          */
  1501.         (void)sprintf(prntscrnbuf, "%c%s%c",
  1502.                   CH(VE), map, CH(VE));
  1503.         use_value2          mvaddstr(orow + 1, 0, prntscrnbuf);
  1504.  
  1505. #endif
  1506.         }
  1507.         for (j = 0; j < MAX_WIDTH / RATIO; j++)
  1508.         map[j] = ' ';
  1509.         orow = row;
  1510.     }
  1511.     for (j = 0; j < MAX_WIDTH; j++) {
  1512.         col = j / RATIO;
  1513.         tmp = loc_symbol(i, j);
  1514.         if (priority[map[col]] < priority[tmp])
  1515.         map[col] = tmp;
  1516.         if (map[col] == '@') {
  1517.         mycol = col + 1;   /* account for border */
  1518.         myrow = row + 1;
  1519.         }
  1520.     }
  1521.     }
  1522.     if (orow >= 0) {
  1523. #ifdef MAC
  1524.     DSetScreenCursor(0, orow + 1);
  1525.     DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
  1526.     DWriteScreenString(map);
  1527.     DWriteScreenCharAttr(CH(VE), ATTR_NORMAL);
  1528. #else
  1529.     (void)sprintf(prntscrnbuf, "%c%s%c",
  1530.               CH(VE), map, CH(VE));
  1531.     use_value2          mvaddstr(orow + 1, 0, prntscrnbuf);
  1532.  
  1533. #endif
  1534.     }
  1535. #ifdef MAC
  1536.     DSetScreenCursor(0, orow + 2);
  1537.     DWriteScreenCharAttr(CH(BL), ATTR_NORMAL);
  1538.     for (i = 0; i < MAX_WIDTH / RATIO; i++)
  1539.     DWriteScreenCharAttr(CH(HE), ATTR_NORMAL);
  1540.     DWriteScreenCharAttr(CH(BR), ATTR_NORMAL);
  1541. #else
  1542.     use_value2          mvaddch(orow + 2, 0, CH(BL));
  1543.  
  1544.     for (i = 0; i < MAX_WIDTH / RATIO; i++)
  1545.     (void)addch(CH(HE));
  1546.     (void)addch(CH(BR));
  1547. #endif
  1548.  
  1549. #ifdef MAC
  1550.     DSetScreenCursor(23, 23);
  1551.     DWriteScreenStringAttr("Hit any key to continue", ATTR_NORMAL);
  1552.     if (mycol > 0)
  1553.     DSetScreenCursor(mycol, myrow);
  1554. #else
  1555.     use_value2          mvaddstr(23, 23, "Hit any key to continue");
  1556.  
  1557.     if (mycol > 0)
  1558.     (void)move(myrow, mycol);
  1559. #endif
  1560.     (void)inkey();
  1561.     restore_screen();
  1562. }
  1563.